home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / cagd_lib / sbspeval.c < prev    next >
C/C++ Source or Header  |  1995-12-30  |  12KB  |  303 lines

  1. /******************************************************************************
  2. * SBspEval.c - Bspline surfaces handling routines - evaluation routines.      *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Mar. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include <string.h>
  8. #include "cagd_loc.h"
  9.  
  10. /*****************************************************************************
  11. * DESCRIPTION:                                                               M
  12. * Evaluates the given tensor product Bspline surface at a given point, by    M
  13. * extracting an isoparamteric curve along u from the surface and evaluating  M
  14. * the curve at parameter v.                                                  M
  15. *                                         M
  16. *        u -->                                 V
  17. *     +----------------------+                             V
  18. *     |P0         Pi-1|                             V
  19. *   V |Pi        P2i-1|    Parametric space orientation - control mesh. V
  20. *    ||                 |                             V
  21. *    v|Pn-i         Pn-1|                             V
  22. *     +----------------------+                             V
  23. *                                                                            *
  24. * PARAMETERS:                                                                M
  25. *   Srf:       Surface to evaluate at the given (u, v) location.             M
  26. *   u, v:      Location where to evaluate the surface.                       M
  27. *                                                                            *
  28. * RETURN VALUE:                                                              M
  29. *   CagdRType *:  A vector holding all the coefficients of all components    M
  30. *                 of curve Crv's point type. If for example the curve's      M
  31. *                 point type is P2, the W, X, and Y will be saved in the     M
  32. *                 first three locations of the returned vector. The first    M
  33. *                 location (index 0) of the returned vector is reserved for  M
  34. *                 the rational coefficient W and XYZ always starts at second M
  35. *                 location of the returned vector (index 1).                 M
  36. *                                                                            *
  37. * KEYWORDS:                                                                  M
  38. *   BspSrfEvalAtParam, evaluation, Bsplines                                  M
  39. *****************************************************************************/
  40. CagdRType *BspSrfEvalAtParam(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  41. {
  42.     static CagdCrvStruct
  43.     *IsoSubCrv = NULL;
  44.     CagdRType *Pt, *VBasisFunc, UMin, UMax, VMin, VMax;
  45.     CagdBType
  46.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  47.     int k, UIndexFirst, VIndexFirst,
  48.     UOrder = Srf -> UOrder,
  49.     VOrder = Srf -> VOrder,
  50.         ULength = Srf -> ULength,
  51.         VLength = Srf -> VLength,
  52.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  53.  
  54.     CagdSrfDomain(Srf, &UMin, &UMax, &VMin, &VMax);
  55.     if (u < UMin - EPSILON || u > UMax + EPSILON)
  56.     CAGD_FATAL_ERROR(CAGD_ERR_U_NOT_IN_SRF);
  57.     if (v < VMin - EPSILON || v > VMax + EPSILON)
  58.     CAGD_FATAL_ERROR(CAGD_ERR_V_NOT_IN_SRF);
  59.     if (u > UMax - IRIT_EPSILON * 2)
  60.     u = UMax - IRIT_EPSILON * 2;
  61.     if (v > VMax - IRIT_EPSILON * 2)
  62.     v = VMax - IRIT_EPSILON * 2;
  63.     if (u < UMin)
  64.         u = UMin;
  65.     if (v < VMin)
  66.         v = VMin;
  67.  
  68.     UIndexFirst = BspKnotLastIndexLE(Srf -> UKnotVector,
  69.                      (CAGD_SRF_UPT_LST_LEN(Srf) + UOrder), u) -
  70.                                   (UOrder - 1);
  71.     VBasisFunc = BspCrvCoxDeBoorBasis(Srf -> VKnotVector, VOrder,
  72.                       VLength +
  73.                      (Srf -> VPeriodic ? VOrder - 1 : 0),
  74.                       v, &VIndexFirst);
  75.  
  76.     if (IsoSubCrv != NULL &&
  77.     (Srf -> PType != IsoSubCrv -> PType ||
  78.      UOrder != IsoSubCrv -> Order)) {
  79.     /* The cached curve is not the proper type - release it. */
  80.     CagdCrvFree(IsoSubCrv);
  81.     IsoSubCrv = NULL;
  82.     }
  83.     if (IsoSubCrv == NULL) {
  84.         IsoSubCrv = BspPeriodicCrvNew(UOrder, UOrder, FALSE, Srf -> PType);
  85.     }
  86.     CAGD_GEN_COPY(IsoSubCrv -> KnotVector,
  87.           &Srf -> UKnotVector[UIndexFirst],
  88.           sizeof(CagdRType) * UOrder * 2);
  89.  
  90.     for (k = 0; k < UOrder; k++) {
  91.     int l;
  92.  
  93.     for (l = IsNotRational; l <= MaxCoord; l++) {
  94.         int i,
  95.         VIndexFirstTmp = VIndexFirst;
  96.         CagdRType
  97.             *SrfP = &Srf -> Points[l][CAGD_MESH_UV(Srf,
  98.                           UIndexFirst,
  99.                           VIndexFirstTmp)],
  100.             *CrvP = &IsoSubCrv -> Points[l][k];
  101.  
  102.         *CrvP = 0.0;
  103.         for (i = 0; i < VOrder; i++) {
  104.         *CrvP += VBasisFunc[i] * *SrfP;
  105.         if (++VIndexFirstTmp >= VLength) {
  106.             VIndexFirstTmp -= VLength;
  107.             SrfP -= VLength * CAGD_NEXT_V(Srf);
  108.         }
  109.         else
  110.             SrfP += CAGD_NEXT_V(Srf);
  111.         }
  112.     }
  113.  
  114.     if (++UIndexFirst >= ULength)
  115.         UIndexFirst -= ULength;
  116.     }
  117.  
  118.     Pt = BspCrvEvalAtParam(IsoSubCrv, u);
  119.  
  120.     return Pt;
  121. }
  122.  
  123. /*****************************************************************************
  124. * DESCRIPTION:                                                               M
  125. * Same as BspSrfEvalAtParam above. Cleaner, but much less efficient.         M
  126. *****************************************************************************/
  127. CagdRType *BspSrfEvalAtParam2(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  128. {
  129.     CagdRType *Pt;
  130.     CagdCrvStruct
  131.     *IsoCrv = BspSrfCrvFromSrf(Srf, u, CAGD_CONST_U_DIR);
  132.  
  133.     if (!BspKnotParamInDomain(IsoCrv -> KnotVector, IsoCrv -> Length,
  134.                   IsoCrv -> Order, IsoCrv -> Periodic, v))
  135.     CAGD_FATAL_ERROR(CAGD_ERR_V_NOT_IN_SRF);
  136.  
  137.     Pt = BspCrvEvalAtParam(IsoCrv, v);
  138.  
  139.     CagdCrvFree(IsoCrv);
  140.  
  141.     return Pt;
  142. }
  143.  
  144. /*****************************************************************************
  145. * DESCRIPTION:                                                               M
  146. * Extracts an isoparametric curve out of the given tensor product Bspline    M
  147. * surface in direction Dir at the parameter value of t.                      M
  148. *   Operations should prefer the CONST_U_DIR, in which the extraction is     M
  149. * somewhat faster if that is possible.                         M
  150. *                                                                            *
  151. * PARAMETERS:                                                                M
  152. *   Srf:       To extract an isoparametric ocurve from.                      M
  153. *   t:         Parameter value of extracted isoparametric curve.             M
  154. *   dir:       Direction of the isocurve on the surface. Either U or V.      M
  155. *                                                                            *
  156. * RETURN VALUE:                                                              M
  157. *   CagdCrvStruct *:  An isoparametric curve of Srf. This curve inherits the M
  158. *              order and continuity of surface Srf in direction Dir.  M
  159. *                                                                            *
  160. * KEYWORDS:                                                                  M
  161. *   BspSrfCrvFromSrf, isoparametric curves, curve from surface               M
  162. *****************************************************************************/
  163. CagdCrvStruct *BspSrfCrvFromSrf(CagdSrfStruct *Srf,
  164.                 CagdRType t,
  165.                 CagdSrfDirType dir)
  166. {
  167.     CagdCrvStruct
  168.     *Crv = NULL;
  169.     CagdBType
  170.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  171.     int i, j, CrvLen,
  172.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  173.     CagdRType *CrvP, *SrfP;
  174.  
  175.     switch (dir) {
  176.     case CAGD_CONST_U_DIR:
  177.         if (!BspKnotParamInDomain(Srf -> UKnotVector, Srf -> ULength,
  178.                       Srf -> UOrder, Srf -> UPeriodic, t))
  179.         CAGD_FATAL_ERROR(CAGD_ERR_U_NOT_IN_SRF);
  180.         Crv = BspPeriodicCrvNew(CrvLen = Srf -> VLength, Srf -> VOrder,
  181.                     Srf -> VPeriodic, Srf -> PType);
  182.         CAGD_GEN_COPY(Crv -> KnotVector, Srf -> VKnotVector,
  183.               sizeof(CagdRType) *
  184.                   (CAGD_SRF_VPT_LST_LEN(Srf) + Srf -> VOrder));
  185.  
  186.         for (i = IsNotRational; i <= MaxCoord; i++) {
  187.         CrvP = Crv -> Points[i];
  188.         SrfP = Srf -> Points[i];
  189.         for (j = 0; j < CrvLen; j++) {
  190.             *CrvP++ = BspCrvEvalVecAtParam(SrfP, CAGD_NEXT_U(Srf),
  191.                     Srf -> UKnotVector, Srf -> UOrder,
  192.                     Srf -> ULength, Srf -> UPeriodic, t);
  193.             SrfP += CAGD_NEXT_V(Srf);
  194.         }
  195.         }
  196.         break;
  197.     case CAGD_CONST_V_DIR:
  198.         if (!BspKnotParamInDomain(Srf -> VKnotVector, Srf -> VLength,
  199.                       Srf -> VOrder, Srf -> VPeriodic, t))
  200.         CAGD_FATAL_ERROR(CAGD_ERR_V_NOT_IN_SRF);
  201.         Crv = BspPeriodicCrvNew(CrvLen = Srf -> ULength, Srf -> UOrder,
  202.                     Srf -> UPeriodic, Srf -> PType);
  203.         CAGD_GEN_COPY(Crv -> KnotVector, Srf -> UKnotVector,
  204.               sizeof(CagdRType) *
  205.                   (CAGD_SRF_UPT_LST_LEN(Srf) + Srf -> UOrder));
  206.  
  207.         for (i = IsNotRational; i <= MaxCoord; i++) {
  208.         CrvP = Crv -> Points[i];
  209.         SrfP = Srf -> Points[i];
  210.         for (j = 0; j < CrvLen; j++) {
  211.             *CrvP++ = BspCrvEvalVecAtParam(SrfP, CAGD_NEXT_V(Srf),
  212.                     Srf -> VKnotVector, Srf -> VOrder,
  213.                     Srf -> VLength, Srf -> VPeriodic, t);
  214.             SrfP += CAGD_NEXT_U(Srf);
  215.         }
  216.         }
  217.         break;
  218.     default:
  219.         CAGD_FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  220.         break;
  221.     }
  222.     return Crv;
  223. }
  224.  
  225. /*****************************************************************************
  226. * DESCRIPTION:                                                               M
  227. * Extracts a curve from the mesh of a tensor product Bspline surface Srf in  M
  228. * direction Dir at index Index.                                              M
  229. *                                                                            *
  230. * PARAMETERS:                                                                M
  231. *   Srf:       To extract a curve from.                               M
  232. *   Index:     Index along the mesh of Srf to extract the curve from.        M
  233. *   Dir:       Direction of extracted curve. Either U or V.             M
  234. *                                                                            *
  235. * RETURN VALUE:                                                              M
  236. *   CagdCrvStruct *:   A curve from Srf. This curve inherit the order and    M
  237. *                      continuity of surface Srf in direction Dir. However,  M
  238. *                      thiscurve is not on surface Srf, in general.          M
  239. *                                                                            *
  240. * KEYWORDS:                                                                  M
  241. *   BspSrfCrvFromMesh, isoparametric curves, curve from mesh                 M
  242. *****************************************************************************/
  243. CagdCrvStruct *BspSrfCrvFromMesh(CagdSrfStruct *Srf,
  244.                  int Index,
  245.                  CagdSrfDirType Dir)
  246. {
  247.     CagdCrvStruct
  248.     *Crv = NULL;
  249.     CagdBType
  250.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  251.     int i, j, CrvLen,
  252.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  253.     CagdRType *CrvP, *SrfP;
  254.  
  255.     switch (Dir) {
  256.     case CAGD_CONST_U_DIR:
  257.         if (Index >= CAGD_SRF_UPT_LST_LEN(Srf) || Index < 0)
  258.         CAGD_FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  259.  
  260.         Index %= Srf -> ULength;
  261.         Crv = BspPeriodicCrvNew(CrvLen = Srf -> VLength, Srf -> VOrder,
  262.                     Srf -> VPeriodic, Srf -> PType);
  263.         CAGD_GEN_COPY(Crv -> KnotVector, Srf -> VKnotVector,
  264.               sizeof(CagdRType) *
  265.                   (CAGD_SRF_VPT_LST_LEN(Srf) + Srf -> VOrder));
  266.  
  267.         for (i = IsNotRational; i <= MaxCoord; i++) {
  268.         CrvP = Crv -> Points[i];
  269.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_U(Srf);
  270.         for (j = 0; j < CrvLen; j++) {
  271.             *CrvP++ = *SrfP;
  272.             SrfP += CAGD_NEXT_V(Srf);
  273.         }
  274.         }
  275.         break;
  276.     case CAGD_CONST_V_DIR:
  277.         if (Index >= CAGD_SRF_VPT_LST_LEN(Srf) || Index < 0)
  278.         CAGD_FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  279.  
  280.         Index %= Srf -> VLength;
  281.         Crv = BspPeriodicCrvNew(CrvLen = Srf -> ULength, Srf -> UOrder,
  282.                     Srf -> UPeriodic, Srf -> PType);
  283.         CAGD_GEN_COPY(Crv -> KnotVector, Srf -> UKnotVector,
  284.               sizeof(CagdRType) *
  285.                   (CAGD_SRF_UPT_LST_LEN(Srf) + Srf -> UOrder));
  286.  
  287.         for (i = IsNotRational; i <= MaxCoord; i++) {
  288.         CrvP = Crv -> Points[i];
  289.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_V(Srf);
  290.         for (j = 0; j < CrvLen; j++) {
  291.             *CrvP++ = *SrfP;
  292.             SrfP += CAGD_NEXT_U(Srf);
  293.         }
  294.         }
  295.         break;
  296.     default:
  297.         CAGD_FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  298.         break;
  299.     }
  300.     return Crv;
  301. }
  302.  
  303.